package com.networklib.http.impl;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;

public class ProgressResponseBodyImpl extends ResponseBody {
    private final ResponseBody responseBody;
    private final ProgressResponseBodyImpl.ProgressListener progressListener;
    private BufferedSource bufferedSource;

    public ProgressResponseBodyImpl(ResponseBody responseBody, ProgressResponseBodyImpl.ProgressListener progressListener) {
        this.responseBody = responseBody;
        this.progressListener = progressListener;
    }

    public MediaType contentType() {
        return this.responseBody.contentType();
    }

    @Override
    public long contentLength() {
        return this.responseBody.contentLength();
    }

    @Override
    public BufferedSource source() {
        if (this.bufferedSource == null) {
            this.bufferedSource = Okio.buffer(this.source(this.responseBody.source()));
        }

        return this.bufferedSource;
    }

    private Source source(final Source source) {
        return new ForwardingSource(source) {
            long totalBytesRead = 0L;

            public long read(Buffer sink, long byteCount) throws IOException {
                long bytesRead = super.read(sink, byteCount);
                this.totalBytesRead += bytesRead != -1L ? bytesRead : 0L;
                if (progressListener != null) {
                    progressListener.update(this.totalBytesRead, ProgressResponseBodyImpl.this.responseBody.contentLength(), bytesRead == -1L);
                }
                return bytesRead;
            }
        };
    }

    public interface ProgressListener {
        void update(long bytesRead, long contentLength, boolean done);
    }
}